ti: k3: drivers: ti_sci: Add support for Processor control
authorAndrew F. Davis <afd@ti.com>
Fri, 4 May 2018 19:06:13 +0000 (19:06 +0000)
committerAndrew F. Davis <afd@ti.com>
Wed, 22 Aug 2018 15:57:19 +0000 (10:57 -0500)
TI-SCI message protocol provides support for controlling of various
physical cores available in the SoC. In order to control which host is
capable of controlling a physical processor core, there is a processor
access control list that needs to be populated as part of the board
configuration data.

Introduce support for the set of TI-SCI message protocol APIs that
provide us with this capability of controlling physical cores.

Signed-off-by: Andrew F. Davis <afd@ti.com>
Reviewed-by: Andreas Dannenberg <dannenberg@ti.com>
plat/ti/k3/common/drivers/ti_sci/ti_sci.c
plat/ti/k3/common/drivers/ti_sci/ti_sci.h

index f5d2ce186a1749f36f5d72c244a96c88defa81de..7ba0267dcc31ce38967ecdbc3660750878239c44 100644 (file)
@@ -1152,6 +1152,311 @@ int ti_sci_core_reboot(void)
        return 0;
 }
 
+/**
+ * ti_sci_proc_request() - Request a physical processor control
+ *
+ * @proc_id:   Processor ID this request is for
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_request(uint8_t proc_id)
+{
+       struct ti_sci_msg_req_proc_request req;
+       struct ti_sci_msg_hdr resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_REQUEST,
+                                   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                   &req, sizeof(req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       req.processor_id = proc_id;
+
+       ret = ti_sci_do_xfer(&xfer);
+       if (ret) {
+               ERROR("Transfer send failed (%d)\n", ret);
+               return ret;
+       }
+
+       if (!ti_sci_is_response_ack(&resp))
+               return -ENODEV;
+
+       return 0;
+}
+
+/**
+ * ti_sci_proc_release() - Release a physical processor control
+ *
+ * @proc_id:   Processor ID this request is for
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_release(uint8_t proc_id)
+{
+       struct ti_sci_msg_req_proc_release req;
+       struct ti_sci_msg_hdr resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_RELEASE,
+                                   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                   &req, sizeof(req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       req.processor_id = proc_id;
+
+       ret = ti_sci_do_xfer(&xfer);
+       if (ret) {
+               ERROR("Transfer send failed (%d)\n", ret);
+               return ret;
+       }
+
+       if (!ti_sci_is_response_ack(&resp))
+               return -ENODEV;
+
+       return 0;
+}
+
+/**
+ * ti_sci_proc_handover() - Handover a physical processor control to a host in
+ *                          the processor's access control list.
+ *
+ * @proc_id:   Processor ID this request is for
+ * @host_id:   Host ID to get the control of the processor
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id)
+{
+       struct ti_sci_msg_req_proc_handover req;
+       struct ti_sci_msg_hdr resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_HANDOVER,
+                                   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                   &req, sizeof(req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       req.processor_id = proc_id;
+       req.host_id = host_id;
+
+       ret = ti_sci_do_xfer(&xfer);
+       if (ret) {
+               ERROR("Transfer send failed (%d)\n", ret);
+               return ret;
+       }
+
+       if (!ti_sci_is_response_ack(&resp))
+               return -ENODEV;
+
+       return 0;
+}
+
+/**
+ * ti_sci_proc_set_boot_cfg() - Set the processor boot configuration flags
+ *
+ * @proc_id:           Processor ID this request is for
+ * @config_flags_set:  Configuration flags to be set
+ * @config_flags_clear:        Configuration flags to be cleared
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector,
+                            uint32_t config_flags_set,
+                            uint32_t config_flags_clear)
+{
+       struct ti_sci_msg_req_set_proc_boot_config req;
+       struct ti_sci_msg_hdr resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CONFIG,
+                                   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                   &req, sizeof(req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       req.processor_id = proc_id;
+       req.bootvector_low = bootvector & TISCI_ADDR_LOW_MASK;
+       req.bootvector_high = (bootvector & TISCI_ADDR_HIGH_MASK) >>
+                               TISCI_ADDR_HIGH_SHIFT;
+       req.config_flags_set = config_flags_set;
+       req.config_flags_clear = config_flags_clear;
+
+       ret = ti_sci_do_xfer(&xfer);
+       if (ret) {
+               ERROR("Transfer send failed (%d)\n", ret);
+               return ret;
+       }
+
+       if (!ti_sci_is_response_ack(&resp))
+               return -ENODEV;
+
+       return 0;
+}
+
+/**
+ * ti_sci_proc_set_boot_ctrl() - Set the processor boot control flags
+ *
+ * @proc_id:                   Processor ID this request is for
+ * @control_flags_set:         Control flags to be set
+ * @control_flags_clear:       Control flags to be cleared
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set,
+                             uint32_t control_flags_clear)
+{
+       struct ti_sci_msg_req_set_proc_boot_ctrl req;
+       struct ti_sci_msg_hdr resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CTRL,
+                                   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                   &req, sizeof(req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       req.processor_id = proc_id;
+       req.control_flags_set = control_flags_set;
+       req.control_flags_clear = control_flags_clear;
+
+       ret = ti_sci_do_xfer(&xfer);
+       if (ret) {
+               ERROR("Transfer send failed (%d)\n", ret);
+               return ret;
+       }
+
+       if (!ti_sci_is_response_ack(&resp))
+               return -ENODEV;
+
+       return 0;
+}
+
+/**
+ * ti_sci_proc_auth_boot_image() - Authenticate and load image and then set the
+ *                                 processor configuration flags
+ *
+ * @proc_id:   Processor ID this request is for
+ * @cert_addr: Memory address at which payload image certificate is located
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr)
+{
+       struct ti_sci_msg_req_proc_auth_boot_image req;
+       struct ti_sci_msg_hdr resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_AUTH_BOOT_IMIAGE,
+                                   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                   &req, sizeof(req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       req.processor_id = proc_id;
+       req.cert_addr_low = cert_addr & TISCI_ADDR_LOW_MASK;
+       req.cert_addr_high = (cert_addr & TISCI_ADDR_HIGH_MASK) >>
+                               TISCI_ADDR_HIGH_SHIFT;
+
+       ret = ti_sci_do_xfer(&xfer);
+       if (ret) {
+               ERROR("Transfer send failed (%d)\n", ret);
+               return ret;
+       }
+
+       if (!ti_sci_is_response_ack(&resp))
+               return -ENODEV;
+
+       return 0;
+}
+
+/**
+ * ti_sci_proc_get_boot_status() - Get the processor boot status
+ *
+ * @proc_id:   Processor ID this request is for
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
+                               uint32_t *cfg_flags,
+                               uint32_t *ctrl_flags,
+                               uint32_t *sts_flags)
+{
+       struct ti_sci_msg_req_get_proc_boot_status req;
+       struct ti_sci_msg_resp_get_proc_boot_status resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_GET_PROC_BOOT_STATUS,
+                                   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                   &req, sizeof(req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       req.processor_id = proc_id;
+
+       ret = ti_sci_do_xfer(&xfer);
+       if (ret) {
+               ERROR("Transfer send failed (%d)\n", ret);
+               return ret;
+       }
+
+       if (!ti_sci_is_response_ack(&resp))
+               return -ENODEV;
+
+       *bv = (resp.bootvector_low & TISCI_ADDR_LOW_MASK) |
+             (((uint64_t)resp.bootvector_high << TISCI_ADDR_HIGH_SHIFT) &
+              TISCI_ADDR_HIGH_MASK);
+       *cfg_flags = resp.config_flags;
+       *ctrl_flags = resp.control_flags;
+       *sts_flags = resp.status_flags;
+
+       return 0;
+}
+
 /**
  * ti_sci_init() - Basic initialization
  *
index df0c13ec10a43c91f58e5835030852815d1eaaac..e40ad6bc51c34a6cf9301b22c166e9f5035a63e1 100644 (file)
@@ -161,6 +161,43 @@ int ti_sci_clock_get_freq(uint32_t dev_id, uint8_t clk_id, uint64_t *freq);
  */
 int ti_sci_core_reboot(void);
 
+/**
+ * Processor control operations
+ *
+ * - ti_sci_proc_request - Command to request a physical processor control
+ * - ti_sci_proc_release - Command to release a physical processor control
+ * - ti_sci_proc_handover - Command to handover a physical processor control to
+ *                          a host in the processor's access control list.
+ *              @host_id: Host ID to get the control of the processor
+ * - ti_sci_proc_set_boot_cfg - Command to set the processor boot configuration flags
+ *              @config_flags_set: Configuration flags to be set
+ *              @config_flags_clear: Configuration flags to be cleared.
+ * - ti_sci_proc_set_boot_ctrl - Command to set the processor boot control flags
+ *              @control_flags_set: Control flags to be set
+ *              @control_flags_clear: Control flags to be cleared
+ * - ti_sci_proc_auth_boot_image - Command to authenticate and load the image
+ *                                 and then set the processor configuration flags.
+ *              @cert_addr: Memory address at which payload image certificate is located.
+ * - ti_sci_proc_get_boot_status - Command to get the processor boot status
+ *
+ * NOTE: for all these functions, the following are generic in nature:
+ * @proc_id:   Processor ID
+ * Returns 0 for successful request, else returns corresponding error message.
+ */
+int ti_sci_proc_request(uint8_t proc_id);
+int ti_sci_proc_release(uint8_t proc_id);
+int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id);
+int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector,
+                            uint32_t config_flags_set,
+                            uint32_t config_flags_clear);
+int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set,
+                             uint32_t control_flags_clear);
+int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr);
+int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
+                               uint32_t *cfg_flags,
+                               uint32_t *ctrl_flags,
+                               uint32_t *sts_flags);
+
 /**
  * ti_sci_init() - Basic initialization
  *